<template>
  <h3>自动推导</h3>
  <p>{{ user }}</p>
  <h3>显式标注</h3>
  <p>{{ user1 }}</p>
  <button @click="handChange">改变数据</button>
  <hr />
  <h3>A组件</h3>
  <UserA />
  <h3>B组件</h3>
  <UserB />
</template>

<script setup lang="ts">
import { reactive } from 'vue'
import UserA from '@/components/UserA.vue'
import UserB from '@/components/UserB.vue'
defineOptions({ name: 'PageReactive' })
// 推断出user类型为 { name: string, age: number }
const user = reactive({
  name: 'chaichai',
  age: 18
})

user.name = 'new name' // ok
// 自定义类型
type User = {
  name: string
  age: number
  gender?: string
}

// 显式标注
// 1. 限制传入reactive函数的初始值类型
// 2. 在对user赋值时对新值有类型要求
// 3. 在后续对user的使用时有类型提示
// 4. 不推荐使用 reactive() 的泛型参数，因为处理了深层次 ref 解包的返回值与泛型参数的类型不同。

let user1: User = reactive({
  name: '张三',
  age: 18
})
user1.age = 10 // ok
user1.gender = 'man' // ok
// reactive一般不整体替换
/* 
const handChange = () => {
  user1 = { name: '张三', age: 18 }
}这种写法说错误的
*/
// 可以用Object.assign()来替换
const handChange = () => {
  user1 = Object.assign(user1, { name: '李四', age: 22, gender: undefined })
}
</script>

<style scoped lang="scss"></style>
